package com.iretailer.report.service;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.iretailer.report.dto.PageResult;
import com.iretailer.report.dto.QueryOption;
import com.iretailer.report.mapper.CameraMapper;
import com.iretailer.report.mapper.PhysicalZoneCameraZoneMapper;
import com.iretailer.report.model.*;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author Bennie
 * @Auther: xjw
 * @Date: 2019/1/24 10:42
 * @Description:
 */
@Service
public class CameraService extends ServiceImpl<CameraMapper, Camera> {

    private final CameraMapper cameraMapper;
    private final CameraZoneService cameraZoneService;
    private final PhysicalZoneCameraZoneMapper physicalZoneCameraZoneMapper;
    private final UserMallService userMallService;

    public CameraService(CameraMapper cameraMapper, CameraZoneService cameraZoneService, PhysicalZoneCameraZoneMapper physicalZoneCameraZoneMapper, UserMallService userMallService) {
        this.cameraMapper = cameraMapper;
        this.cameraZoneService = cameraZoneService;
        this.physicalZoneCameraZoneMapper = physicalZoneCameraZoneMapper;
        this.userMallService = userMallService;
    }


    public PageResult<CameraMall> grid(String userId, Integer enable, String cameraStatus, String mallName, String deviceId, QueryOption queryOption) {
        Page page = new Page<CameraMall>(1, Long.MAX_VALUE);
        QueryWrapper queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("1", 1);
        if (enable != null) {
            queryWrapper.eq("enabled", enable);
        }
        if (cameraStatus != null) {
            queryWrapper.eq("cameraStatus", cameraStatus);
        }
        if (mallName != null) {
            queryWrapper.like("mallName", mallName);
        }
        if (deviceId != null) {
            queryWrapper.like("deviceId", deviceId);
        }
        queryOption.judge(page, queryWrapper);
        if (userId != null) {
//            List<String> childens = userService.getTreeId(userId);
//            childens.add(userId);
//            List<String> mallIds = userMallService.selectMallIdsByUserIds(childens);
//            if (mallIds.size() == 0) {
//                mallIds.add("1");
//            }
            List<String> mallIds = userMallService.selectUserMallIds(userId);
            queryWrapper.in("mallId", mallIds);
        }
        cameraMapper.selectPageCameras(page, queryWrapper);
        return new PageResult<>(page.getTotal(), page.getRecords());
    }


    @Cacheable(value = "selectCamera_deviceId", key = "#deviceId")
    public Camera selectByDeviceId(String deviceId) {
        return cameraMapper.selectOne(new QueryWrapper<Camera>().eq("DeviceId", deviceId));
    }

    // 主要用于更新数据 和更新缓存
    @CachePut(value = "selectCamera_deviceId", key = "#camera.deviceId")
    public Camera analysisUpdateCamera(Camera camera) {
        cameraMapper.updateById(camera);
        return camera;
    }

    @CacheEvict(value = "selectCamera_deviceId", key = "#camera.deviceId", allEntries = true)
    @Transactional(propagation = Propagation.REQUIRED)
    public boolean saveOrUpdateCamera(Camera camera, List<CameraZone> cameraZones, String userName) {
        if (cameraZones != null && cameraZones.size() > 0) {
            Long id = camera.getId();
            camera.setUpdateUser(userName);
            camera.setZoneCount(cameraZones.size());
            if (id != null) {
                cameraMapper.updateById(camera);
                // 查询Camera 之前的Id 过滤 如果没有就删除
                List<CameraZone> find = cameraZoneService.list(new QueryWrapper<CameraZone>().lambda().eq(CameraZone::getCameraId, id).orderByAsc(CameraZone::getZone));
                Map<Long, CameraZone> cameraZoneMap = cameraZones.stream().collect(Collectors.toMap(CameraZone::getId, a -> a));
                find.forEach(it -> {
                    CameraZone cameraZone = cameraZoneMap.get(it.getId());
                    if (cameraZone == null) {
                        cameraZoneService.deleteById(it.getId());
                    }
                });
            } else {
                LocalDateTime now = LocalDateTime.now();
                camera.setCreateTime(now);
                camera.setUpdateTime(now);
                cameraMapper.insert(camera);
            }

            //保存 更新 cameraZone
            cameraZones.forEach(it -> {
                //如果一个设备 停用，那么这个设备上的所有zone 停用
                if (camera.getEnabled() == -1) {
                    it.setEnabled(-1);
                }
                it.setCameraId(camera.getId());
                cameraZoneService.saveOrUpdate(it, userName);
            });

            return true;
        } else {
            return false;
        }
    }

    public int insert(Camera camera) {
        return cameraMapper.insert(camera);
    }

    @CacheEvict(value = "selectCamera_deviceId", allEntries = true)
    @Transactional(propagation = Propagation.REQUIRED)
    public boolean deleteCamera(List<Long> ids) {
        if (ids != null) {
            //查出 CameraZoneIds
            List<Long> cameraZoneIds = new ArrayList<>();
            List<CameraZone> cameraZones = cameraZoneService.list(new QueryWrapper<CameraZone>().lambda().in(CameraZone::getCameraId, ids));
            if (cameraZones != null && cameraZones.size() > 0) {
                for (CameraZone cz : cameraZones) {
                    cameraZoneIds.add(cz.getId());
                }
            }
            //查看和 PhysicalZone 有没有关联
            List<PhysicalZoneCameraZone> pzczs = physicalZoneCameraZoneMapper
                    .selectList(new QueryWrapper<PhysicalZoneCameraZone>().lambda().in(PhysicalZoneCameraZone::getCameraZoneId, cameraZoneIds));
            if (cameraZones != null && pzczs.size() > 0) {
                return false;
            } else {
                removeByIds(ids);
                cameraZoneService.remove(new QueryWrapper<CameraZone>().lambda().in(CameraZone::getCameraId, ids));
                return true;
            }
        } else {
            return false;
        }
    }

    public List<CameraTypeCount> getCameraTypeCount(String companyId) {
        return cameraMapper.getCameraTypeCount(companyId);
    }

    public List<CameraMall> selectCameras(Wrapper wrapper) {
        return cameraMapper.selectCameras(wrapper);
    }
}
